import {
  CallHandler,
  ExecutionContext,
  Injectable,
  NestInterceptor,
} from '@nestjs/common';
import { Request } from 'express';
import { Pagination } from 'nestjs-typeorm-paginate';
import { map, Observable } from 'rxjs';

interface IndexInterceptorOption<T> {
  formatter?: (v: T[]) => any;
}

@Injectable()
export class IndexInterceptor<T = any> implements NestInterceptor {
  constructor(private options?: IndexInterceptorOption<T>) {}
  intercept(
    context: ExecutionContext,
    next: CallHandler<Pagination<T>>,
  ): Observable<SC.API.IndexInterface<T>> {
    const request = context
      .switchToHttp()
      .getRequest<Request<{}, {}, { size: number }>>();

    const { size = 10 } = request.body;

    return next.handle().pipe(
      map((data) => {
        const { totalItems, totalPages, currentPage } = data.meta;

        const res: SC.API.IndexInterface<T> = {
          content: this.options?.formatter
            ? this.options.formatter(data.items)
            : data.items,
          number: currentPage - 1,
          size: size,
          totalElements: totalItems!,
          totalPages: totalPages!,
          first: currentPage === 1,
          last: currentPage >= (totalPages || 0),
        };

        return res;
      }),
    );
  }
}
